package com.example.demo.future;

import com.google.common.util.concurrent.*;
import com.sun.istack.Nullable;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @description: xxx
 * @time: 2020-12-12 13:31
 * @author: baojinlong
 **/
public class GuavaFutureDemo {
    public static void main(String[] args) throws Exception {
        // 除了上面的 addListener 方法外，其实我更喜欢用 FutureCallback 的方式
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神：我开始化妆了，好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            throw new Exception("男神约我看电影，就不和你吃饭了。");
            // return "化妆完毕了。";
        });
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(@Nullable String result) {
                System.out.println(Thread.currentThread().getName() + "-future的内容:" + result);
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println(Thread.currentThread().getName() + "-女神放你鸽子了。");
                t.printStackTrace();
            }
        });
        System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }

    /**
     * 添加监听:获取运行结果是在另外的线程里面执行的，完全没有阻塞主线程
     * 那么我们就需要在异步任务提交之后，注册一个回调函数就行
     *
     * @throws InterruptedException
     */
    private static void method01() throws InterruptedException {
        // 需要用 Guava 里面的 MoreExecutors 方法装饰一下
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
        // 然后用装饰后的 executor 调用 submit 方法（任意一种），就会返回 ListenableFuture ，拿到这个 ListenableFuture 之后，我们就可以在上面注册监听：
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神：我开始化妆了，好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            return "化妆完毕了。";
        });

        listenableFuture.addListener(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "-future的内容:" + listenableFuture.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, executor);
        System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }
}
